import math
import numpy as np
import pysvg.filter
import pysvg.gradient 
import pysvg.linking
import pysvg.script
import pysvg.shape
import pysvg.structure
import pysvg.style
import pysvg.text
import pysvg.builders 

class Line:
    def __init__(self, x1, y1, x2, y2):
        self.x = x1
        self.y = y1
        self.m = (y2 - y1)/(x2 - x1)
        self.m_angle = math.atan2(y2 - y1, x2 - x1)

    def add_contour(self, c_mag):
        recip_m_angle = self.m_angle - math.pi/2.0
        del_x = math.cos(recip_m_angle)*c_mag
        del_y = math.sin(recip_m_angle)*c_mag
        new_x = self.x + del_x
        new_y = self.y + del_y
        return Line(new_x, new_y, new_x + math.cos(self.m_angle), new_y + math.sin(self.m_angle))

    def find_intersection(self, line2):
        int_x = (line2.y - self.y + self.x*self.m - line2.m*line2.x)/(self.m - line2.m)
        int_y = line2.m*(int_x-line2.x) + line2.y
        return int_x, int_y

def parse_dat(input_str, scale, offset, bottom_width):
    #Here is where the file is parsed. Any file parsing that needs to be hardened should be done here.
    dpi = 96
    linelist = input_str.split('\n')
    linelist_stripped = [line.strip() for line in linelist]
    linelist_stripped.pop(0)
    points_str = [line.split() for line in linelist_stripped]
    points_str = filter(lambda x: len(x)>0, points_str)

    #From here on, it is assumed points_str is a list of lists of strings that represent the points in the correct order. They will be floatified.
    points_float = [map(float, points) for points in points_str]
    scaled_points = [map(lambda x:x*scale*dpi, points) for points in points_float]
    foil_lines = []
    for i in range(len(scaled_points) - 1):
        print scaled_points[i+1]
        temp_line = Line(scaled_points[i][0], scaled_points[i][1], scaled_points[i + 1][0], scaled_points[i + 1][1])
        foil_lines.append(temp_line)
    foil_lines_offset = [foil_line.add_contour(offset*dpi) for foil_line in foil_lines]
    offset_points_list = []
    for i in range(len(foil_lines_offset) - 1):
        temp_xy = list(foil_lines_offset[i].find_intersection(foil_lines_offset[i + 1]))
        offset_points_list.append(temp_xy)
    offset_points_list.append(list(foil_lines_offset[0].find_intersection(foil_lines_offset[len(foil_lines_offset)-1])))
    

    #A ShapeBuilder is needed to generate polylines. We'll also need an svg shortly
    shape_builder = pysvg.builders.ShapeBuilder()
    foilsvg = pysvg.structure.svg()

    #This covers generating the rest of the complete template, if one is wanted (template width not 0)
    if bottom_width:
        ledge_width = .25*dpi
        template_separation = .05*dpi
        on_bottom_edge = 0
        bottom_edge_points = []
        for point in offset_points_list:
            if on_bottom_edge:
                new_point = [point[0], point[1] - template_separation]
                bottom_edge_points.append(new_point)
            else:
                if point[1] < 0.0 and point[0] < .1:
                    on_bottom_edge = 1
                    new_point = [point[0], point[1] - template_separation]
                    bottom_edge_points.append(new_point)
                else:
                    pass

        bottom_edge_points.append([bottom_edge_points[len(bottom_edge_points) - 1][0] + ledge_width, bottom_edge_points[len(bottom_edge_points) - 1][1]])
        bottom_edge_points.append([bottom_edge_points[len(bottom_edge_points) - 1][0], bottom_edge_points[len(bottom_edge_points) - 1][1] - dpi*bottom_width])
        bottom_edge_points.append([bottom_edge_points[0][0] - ledge_width, bottom_edge_points[0][1] - dpi*bottom_width])
        bottom_edge_points.append([bottom_edge_points[0][0] - ledge_width, bottom_edge_points[0][1]])
        bottom_edge_points.append(bottom_edge_points[0])
        polyline_bottom_points = ' '.join([','.join(point) for point in [map(str, p) for p in bottom_edge_points]])
        bottom_polyline = shape_builder.createPolyline(polyline_bottom_points, strokewidth=0, stroke='red')
        foilsvg.addElement(bottom_polyline)

    #Add first point to end of points list, otherwise polyline won't complete the line
    offset_points_list.append(offset_points_list[0])
    
    #Super insane one-liner to convert list of lists of floats to string of x,y pairs separated by spaces
    polyline_foil_points = ' '.join([','.join(point) for point in [map(str, p) for p in offset_points_list]])
    foil_polyline = shape_builder.createPolyline(polyline_foil_points, strokewidth=0, stroke='red')
    foilsvg.addElement(foil_polyline)
    return foilsvg.getXML()

if __name__ == '__main__':
    testscale = 5.0
    testoffset = .05
    testw = 1
    bodydata = open('../airfoils/coord_seligFmt/e636.dat').read()
    open('test.svg','w').write(parse_dat(bodydata,testscale, testoffset, testw))
